package list

import (
	"fmt"
	"sort"
	"strings"
	"sync"
)

// Comparable 是一个约束，用于限制泛型类型的可比较性
type Comparable interface {
	int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64 | string
}

// List 是一个类似 Python list 的结构，支持泛型
type List[T Comparable] struct {
	data []T
	m    sync.Mutex // 互斥锁，用于保证并发安全
}

// NewList 创建一个新的 List 实例
func NewList[T Comparable]() *List[T] {
	return &List[T]{
		data: make([]T, 0),
	}
}

// Append 在列表末尾添加一个元素
func (l *List[T]) Append(value T) {
	l.m.Lock()
	defer l.m.Unlock()
	l.data = append(l.data, value)
}

// Len 返回列表的长度
func (l *List[T]) Len() int {
	l.m.Lock()
	defer l.m.Unlock()
	return len(l.data)
}

// Get 获取指定索引的元素
func (l *List[T]) Get(index int) (T, error) {
	l.m.Lock()
	defer l.m.Unlock()
	if index < 0 || index >= len(l.data) {
		var zero T
		return zero, fmt.Errorf("index out of range")
	}
	return l.data[index], nil
}

// Set 设置指定索引的元素
func (l *List[T]) Set(index int, value T) error {
	l.m.Lock()
	defer l.m.Unlock()
	if index < 0 || index >= len(l.data) {
		return fmt.Errorf("index out of range")
	}
	l.data[index] = value
	return nil
}

// Insert 在指定索引处插入一个元素
func (l *List[T]) Insert(index int, value T) error {
	l.m.Lock()
	defer l.m.Unlock()
	if index < 0 || index > len(l.data) {
		return fmt.Errorf("index out of range")
	}
	l.data = append(l.data[:index], append([]T{value}, l.data[index:]...)...)
	return nil
}

// Remove 删除指定索引的元素并返回它
func (l *List[T]) Remove(index int) (T, error) {
	l.m.Lock()
	defer l.m.Unlock()
	if index < 0 || index >= len(l.data) {
		var zero T
		return zero, fmt.Errorf("index out of range: requested index %d, list length %d", index, len(l.data))
	}
	value := l.data[index]
	l.data = append(l.data[:index], l.data[index+1:]...)
	return value, nil
}

// Exists 方法用于检查列表中是否存在指定的值
func (l *List[T]) Exists(value T) bool {
	l.m.Lock()
	defer l.m.Unlock()
	for _, v := range l.data {
		if v == value {
			return true
		}
	}
	return false
}

// Clear 清空列表
func (l *List[T]) Clear() {
	l.m.Lock()
	defer l.m.Unlock()
	l.data = make([]T, 0)
}

// Copy 返回列表的副本
func (l *List[T]) Copy() *List[T] {
	l.m.Lock()
	defer l.m.Unlock()
	newList := NewList[T]()
	newList.data = append(newList.data, l.data...)
	return newList
}

// Reverse 反转列表
func (l *List[T]) Reverse() {
	l.m.Lock()
	defer l.m.Unlock()
	for i, j := 0, len(l.data)-1; i < j; i, j = i+1, j-1 {
		l.data[i], l.data[j] = l.data[j], l.data[i]
	}
}

// ToString 返回列表的字符串表示
func (l *List[T]) ToString() string {
	l.m.Lock()
	defer l.m.Unlock()
	strs := make([]string, len(l.data))
	for i, v := range l.data {
		strs[i] = fmt.Sprintf("%v", v)
	}
	return "[" + strings.Join(strs, ", ") + "]"
}

// Sort 对列表进行排序
func (l *List[T]) Sort() error {
	l.m.Lock()
	defer l.m.Unlock()
	if len(l.data) == 0 {
		return nil
	}
	sort.Slice(l.data, func(i, j int) bool {
		return l.data[i] < l.data[j]
	})
	return nil
}
